/**
 * ============运势控制器模块开始===========
 * 运势控制器 - Fortune Controller
 * 
 * 功能说明：
 * - 处理用户运势相关的API请求，提供个性化运势分析
 * - 基于用户生辰八字和万年历数据计算运势
 * - 支持每日运势、每周运势、每月运势等多种时间维度
 * - 集成fortuneService服务，提供专业的命理学计算
 * 
 * 依赖模块：
 * - fortuneService: 运势计算服务，提供基于八字的运势算法
 * - jwt: JSON Web Token，用于用户身份验证
 * - logger: 日志记录工具，记录关键操作和错误信息
 * 
 * API端点：
 * - GET /fortune/daily: 获取每日运势
 * - GET /fortune/weekly: 获取每周运势
 * - GET /fortune/monthly: 获取每月运势
 * - GET /fortune/zodiac: 获取生肖运势
 * 
 * Handle fortune-related API requests
 */

// 导入依赖模块 - Import required modules
const fortuneService = require('../services/fortuneService');
const jwt = require('jsonwebtoken');
const logger = require('../utils/logger');

/**
 * 运势控制器类 - Fortune Controller Class
 * 
 * 该类封装了所有运势相关的业务逻辑处理方法
 * 每个方法对应一个API端点，负责用户验证、参数处理、运势计算和响应返回
 * 
 * 设计原则：
 * - 用户验证：确保只有登录用户才能获取个性化运势
 * - 数据完整性：验证用户生辰信息的完整性
 * - 算法准确性：基于传统命理学理论进行运势计算
 * - 响应标准化：统一的JSON响应格式
 * - 错误处理：完善的异常处理和日志记录
 */
class FortuneController {
  /**
   * ============获取每日运势功能开始===========
   * 获取用户每日运势
   * Get user's daily fortune
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @returns {Promise<void>} 无返回值，通过res对象返回JSON响应
   * @throws {Error} 当用户验证失败或运势计算失败时抛出异常
   * 
   * 功能说明：
   * - 基于用户生辰八字和指定日期计算个性化运势
   * - 分析五行相生相克关系，提供准确的运势预测
   * - 包含总体运势、事业、财运、感情、健康等多个维度
   * - 提供幸运颜色、幸运数字等实用建议
   * 
   * 算法原理：
   * 1. 根据用户出生日期和时间计算生辰八字
   * 2. 获取指定日期的天干地支信息
   * 3. 分析日柱与用户八字的五行关系
   * 4. 根据传统命理学规则计算各项运势指数
   * 5. 生成个性化的运势建议和幸运元素
   * 
   * 请求参数（Query Parameters）：
   * - date?: 查询日期，格式YYYY-MM-DD，默认为今天
   * 
   * 请求头（Headers）：
   * - Authorization: Bearer JWT令牌（用户身份验证）
   * 
   * 响应格式：
   * {
   *   success: boolean,
   *   message: string,
   *   data: {
   *     date: string,       // 运势日期
   *     user: {
   *       userId: string,
   *       zodiac: string    // 生肖
   *     },
   *     fortune: {
   *       overall: number,    // 总体运势指数（1-100）
   *       career: number,     // 事业运指数
   *       wealth: number,     // 财运指数
   *       love: number,       // 感情运指数
   *       health: number,     // 健康运指数
   *       advice: string,     // 运势建议
   *       luckyColor: string, // 幸运颜色
   *       luckyNumber: number // 幸运数字
   *     }
   *   }
   * }
   * 
   * 使用示例：
   * GET /api/fortune/daily?date=2024-01-15
   * Headers: { Authorization: "Bearer your-jwt-token" }
   * 
   * 异常处理：
   * - 401: 用户未登录或token无效
   * - 400: 用户生辰信息不完整
   * - 500: 服务器内部错误（运势计算失败）
   */
  async getDailyFortune(req, res) {
    try {
      // 第一步：从查询参数中获取日期 - Step 1: Get date from query parameters
      const { date } = req.query;
      logger.info('收到每日运势请求，日期:', date);
      
      // 第二步：获取用户信息 - Step 2: Get user information
      // 在实际应用中，这里应该从JWT token中解析用户信息
      // 目前使用默认用户信息进行测试，便于开发和调试
      // TODO: 实现JWT token解析获取真实用户信息
      const userInfo = {
        userId: 'test-user',      // 用户ID
        birthDate: '1990-01-01',  // 出生日期，用于计算八字
        birthTime: '08:00',       // 出生时间，用于计算时辰
        gender: 'male'            // 性别，影响某些运势计算
      };
      
      logger.info('使用用户信息:', userInfo);
      
      // 第三步：验证用户生辰信息完整性 - Step 3: Validate user birth information completeness
      if (!userInfo.birthDate) {
        return res.status(400).json({
          success: false,
          message: '请先完善个人信息（出生日期）',
          data: null
        });
      }
      
      // 第四步：调用运势服务计算每日运势 - Step 4: Call fortune service to calculate daily fortune
      // fortuneService.getDailyFortune() 会根据用户八字和指定日期计算运势
      // 这个方法会考虑：
      // 1. 用户的生辰八字
      // 2. 当日的天干地支
      // 3. 五行相生相克关系
      // 4. 传统命理学规则
      const dailyFortune = await fortuneService.getDailyFortune(userInfo, date);
      
      logger.info('运势计算结果:', dailyFortune);
      
      // 第五步：返回成功响应 - Step 5: Return success response
      res.json({
        success: true,
        message: '获取每日运势成功',
        data: dailyFortune
      });
    } catch (error) {
      // 第六步：错误处理 - Step 6: Error handling
      // 记录错误日志，便于调试和监控
      logger.error('获取每日运势失败:', error);
      
      // 返回500错误响应，包含错误信息
      res.status(500).json({
        success: false,
        message: '获取每日运势失败，请稍后重试',
        data: null
      });
    }
  }
  
  /**
   * ============获取每周运势功能开始===========
   * 获取用户每周运势
   * Get user's weekly fortune
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @returns {Promise<void>} 无返回值，通过res对象返回JSON响应
   * @throws {Error} 当用户验证失败或运势计算失败时抛出异常
   * 
   * 功能说明：
   * - 基于用户生辰八字计算一周的运势趋势
   * - 分析每日运势变化，提供周度运势概览
   * - 包含本周重点关注事项和建议
   * - 适用于用户进行周度规划和决策参考
   * 
   * 请求参数（Query Parameters）：
   * - startDate?: 周开始日期，格式YYYY-MM-DD，默认为本周一
   * 
   * 请求头（Headers）：
   * - Authorization: Bearer JWT令牌（用户身份验证）
   * 
   * 响应格式：
   * {
   *   success: boolean,
   *   message: string,
   *   data: {
   *     startDate: string,
   *     endDate: string,
   *     weeklyOverview: {
   *       overall: number,
   *       trend: string,
   *       keyFocus: string[]
   *     },
   *     dailyFortunes: [
   *       {
   *         date: string,
   *         overall: number,
   *         highlights: string[]
   *       }
   *     ]
   *   }
   * }
   * 
   * 使用示例：
   * GET /api/fortune/weekly?startDate=2024-01-15
   * Headers: { Authorization: "Bearer your-jwt-token" }
   * 
   * 异常处理：
   * - 401: 用户未登录或token无效
   * - 400: 用户生辰信息不完整
   * - 500: 服务器内部错误
   */
  async getWeeklyFortune(req, res) {
    try {
      // 第一步：获取请求参数 - Step 1: Get request parameters
      const { startDate } = req.query;
      
      // 第二步：验证用户身份 - Step 2: Verify user authentication
      const token = req.headers.authorization?.replace('Bearer ', '');
      
      if (!token) {
        return res.status(401).json({
          success: false,
          message: '请先登录',
          data: null
        });
      }
      
      // 第三步：解析JWT token获取用户信息 - Step 3: Parse JWT token to get user info
      let userInfo;
      try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key');
        userInfo = {
          userId: decoded.userId,
          birthDate: decoded.birthDate,
          birthTime: decoded.birthTime,
          gender: decoded.gender
        };
      } catch (tokenError) {
        return res.status(401).json({
          success: false,
          message: 'Token无效，请重新登录',
          data: null
        });
      }
      
      // 第四步：验证用户生辰信息 - Step 4: Validate user birth information
      if (!userInfo.birthDate) {
        return res.status(400).json({
          success: false,
          message: '请先完善个人信息（出生日期）',
          data: null
        });
      }

      const weeklyFortune = await fortuneService.getWeeklyFortune(userInfo, startDate);
      
      // 第六步：返回成功响应 - Step 6: Return success response
      res.json({
        success: true,
        message: '获取每周运势成功',
        data: weeklyFortune
      });
      
    } catch (error) {
      // 第七步：错误处理 - Step 7: Error handling
      logger.error('获取每周运势失败:', error);
      res.status(500).json({
        success: false,
        message: '获取每周运势失败，请稍后重试',
        data: null
      });
    }
  }

  /**
   * ============获取每月运势功能开始===========
   * 获取用户每月运势
   * Get user's monthly fortune
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @returns {Promise<void>} 无返回值，通过res对象返回JSON响应
   * @throws {Error} 当用户验证失败或运势计算失败时抛出异常
   * 
   * 功能说明：
   * - 基于用户生辰八字计算整月的运势趋势
   * - 分析月度运势变化规律，提供长期规划建议
   * - 包含月度重点事项和关键时间节点
   * - 适用于用户进行月度目标设定和重要决策
   * 
   * 请求参数（Query Parameters）：
   * - year: 年份，整数
   * - month: 月份，整数，范围1-12
   * 
   * 请求头（Headers）：
   * - Authorization: Bearer JWT令牌（用户身份验证）
   * 
   * 响应格式：
   * {
   *   success: boolean,
   *   message: string,
   *   data: {
   *     year: number,
   *     month: number,
   *     monthlyOverview: {
   *       overall: number,
   *       trend: string,
   *       keyEvents: string[],
   *       bestDays: string[],
   *       cautionDays: string[]
   *     },
   *     weeklyBreakdown: [
   *       {
   *         week: number,
   *         startDate: string,
   *         endDate: string,
   *         focus: string,
   *         rating: number
   *       }
   *     ]
   *   }
   * }
   * 
   * 使用示例：
   * GET /api/fortune/monthly?year=2024&month=1
   * Headers: { Authorization: "Bearer your-jwt-token" }
   * 
   * 异常处理：
   * - 401: 用户未登录或token无效
   * - 400: 参数缺失或用户信息不完整
   * - 500: 服务器内部错误
   */
  async getMonthlyFortune(req, res) {
    try {
      // 第一步：获取请求参数 - Step 1: Get request parameters
      const { year, month } = req.query;
      
      // 第二步：参数验证 - Step 2: Parameter validation
      if (!year || !month) {
        return res.status(400).json({
          success: false,
          message: '缺少必要参数：年份和月份',
          data: null
        });
      }
      
      const yearNum = parseInt(year);
      const monthNum = parseInt(month);
      
      if (isNaN(yearNum) || isNaN(monthNum) || monthNum < 1 || monthNum > 12) {
        return res.status(400).json({
          success: false,
          message: '参数格式错误，请提供有效的年份和月份',
          data: null
        });
      }
      
      // 第三步：验证用户身份 - Step 3: Verify user authentication
      const token = req.headers.authorization?.replace('Bearer ', '');
      
      if (!token) {
        return res.status(401).json({
          success: false,
          message: '请先登录',
          data: null
        });
      }
      
      // 第四步：解析用户信息 - Step 4: Parse user information
      let userInfo;
      try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key');
        userInfo = {
          userId: decoded.userId,
          birthDate: decoded.birthDate,
          birthTime: decoded.birthTime,
          gender: decoded.gender
        };
      } catch (tokenError) {
        return res.status(401).json({
          success: false,
          message: 'Token无效，请重新登录',
          data: null
        });
      }
      
      // 第五步：验证用户生辰信息 - Step 5: Validate user birth information
      if (!userInfo.birthDate) {
        return res.status(400).json({
          success: false,
          message: '请先完善个人信息（出生日期）',
          data: null
        });
      }
      
      // 第六步：调用运势服务计算每月运势 - Step 6: Call fortune service to calculate monthly fortune
      const monthlyFortune = await fortuneService.getMonthlyFortune(userInfo, yearNum, monthNum);
      
      // 第七步：返回成功响应 - Step 7: Return success response
      res.json({
        success: true,
        message: '获取每月运势成功',
        data: monthlyFortune
      });
      
    } catch (error) {
      // 第八步：错误处理 - Step 8: Error handling
      logger.error('获取每月运势失败:', error);
      res.status(500).json({
        success: false,
        message: '获取每月运势失败，请稍后重试',
        data: null
      });
    }
  }

  /**
   * ============获取生肖运势功能开始===========
   * 获取生肖运势
   * Get zodiac fortune
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @returns {Promise<void>} 无返回值，通过res对象返回JSON响应
   * @throws {Error} 当参数验证失败或运势计算失败时抛出异常
   * 
   * 功能说明：
   * - 基于传统生肖理论提供生肖运势分析
   * - 不需要用户登录，提供通用的生肖运势信息
   * - 包含当日、当周、当月的生肖运势概况
   * - 适用于用户快速了解生肖运势趋势
   * 
   * 请求参数（Query Parameters）：
   * - zodiac: 生肖名称，如"鼠"、"牛"、"虎"等
   * - period?: 时间周期，可选值："daily"、"weekly"、"monthly"，默认"daily"
   * 
   * 响应格式：
   * {
   *   success: boolean,
   *   message: string,
   *   data: {
   *     zodiac: string,
   *     period: string,
   *     date: string,
   *     fortune: {
   *       overall: number,
   *       career: number,
   *       wealth: number,
   *       love: number,
   *       health: number,
   *       description: string,
   *       advice: string[],
   *       luckyItems: {
   *         colors: string[],
   *         numbers: number[],
   *         directions: string[]
   *       }
   *     }
   *   }
   * }
   * 
   * 使用示例：
   * GET /api/fortune/zodiac?zodiac=龙&period=daily
   * 
   * 异常处理：
   * - 400: 生肖参数缺失或无效
   * - 500: 服务器内部错误
   */
  async getZodiacFortune(req, res) {
    try {
      // 第一步：获取请求参数 - Step 1: Get request parameters
      const { zodiac, period = 'daily' } = req.query;
      
      // 第二步：参数验证 - Step 2: Parameter validation
      if (!zodiac) {
        return res.status(400).json({
          success: false,
          message: '缺少生肖参数',
          data: null
        });
      }
      
      // 第三步：验证生肖有效性 - Step 3: Validate zodiac
      const validZodiacs = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
      if (!validZodiacs.includes(zodiac)) {
        return res.status(400).json({
          success: false,
          message: '无效的生肖参数，请提供正确的生肖名称',
          data: null
        });
      }
      
      // 第四步：验证时间周期参数 - Step 4: Validate period parameter
      const validPeriods = ['daily', 'weekly', 'monthly'];
      if (!validPeriods.includes(period)) {
        return res.status(400).json({
          success: false,
          message: '无效的时间周期参数',
          data: null
        });
      }
      
      // 第五步：调用运势服务计算生肖运势 - Step 5: Call fortune service to calculate zodiac fortune
      const zodiacFortune = await fortuneService.getZodiacFortune(zodiac, period);
      
      // 第六步：返回成功响应 - Step 6: Return success response
      res.json({
        success: true,
        message: '获取生肖运势成功',
        data: zodiacFortune
      });
      
    } catch (error) {
      // 第七步：错误处理 - Step 7: Error handling
      logger.error('获取生肖运势失败:', error);
      res.status(500).json({
        success: false,
        message: '获取生肖运势失败，请稍后重试',
        data: null
      });
    }
  }
}

// 导出控制器实例 - Export controller instance
// 使用单例模式，确保整个应用中只有一个控制器实例
module.exports = new FortuneController();